﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.UI;
using AjaxControlToolkit;
using NetDon.OA.Portal.Constants;
using NetDon.Utilities;
using SD.LLBLGen.Pro.ORMSupportClasses;
using NetDon.OA.Business;
using NetDon.OA.Data.CollectionClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.Linq;
using NetDon.OA.Interface;
using TreeNode = NineRays.WebControls.FlyTreeNode;

namespace NetDon.OA.Portal.Admin
{
    [Function("Admin.Privilege")]
    [Command(ButtonConstants.CommandNames.Save, ButtonConstants.CommandImages.Save, Order = 1)]
    [Navigation("系统管理", "角色权限")]
    public partial class PrivilegeSetting : PageBase
    { 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                LoadModules();
                LoadRoles();
            }
        }

        protected override void OnCommand(System.Web.UI.WebControls.CommandEventArgs args)
        {
            if (args.CommandName == ButtonConstants.CommandNames.Save)
            {
                SavePrivilegeSetting();
            }
        }
        private void LoadRoles()
        {
            string selectedRole = treeRoles.SelectedNode != null ? treeRoles.SelectedNode.Value : null;
            treeRoles.Nodes.Clear();
            var service = ServiceContainer.GetService<ISecurityManageService>();
            foreach (RoleInfo entity in service.GetRoles())
            {
                var node = new TreeNode(entity.RoleName, entity.RoleID.ToString())
                               {
                                   ImageUrl = "~/Images/staff.gif"
                               };
                treeRoles.Nodes.Add(node);
                node.Selected = selectedRole == entity.RoleID.ToString();
            }
            if (treeRoles.SelectedNode == null && treeRoles.Nodes.Count > 0)
            {
                treeRoles.Nodes[0].Selected = true;
            }
            LoadPermission();
        }

        private void LoadModules()
        {
            var service = ServiceContainer.GetService<ISecurityManageService>();
            ModuleCollection collection = service.GetAllModules();
            for (int i = 0; i < collection.Count; i++)
            {
                var moduleNode = new TreeNode
                                     {
                                         Text = collection[i].Name,
                                         Value = collection[i].ModuleID,
                                         IsCheckbox = true
                                     };
                moduleNode.Attributes["Type"] = "Module";
                tvFunctions.Nodes.Add(moduleNode);
                LoadFunctions(moduleNode, collection[i]);
                moduleNode.Expanded = true;
            }
        }

        private static void LoadFunctions(TreeNode parentNode, Module module)
        {
            for (int i = 0; i < module.Functions.Count; i++)
            {
                var node = new TreeNode
                               {
                                   Text =
                                       module.Functions[i].Name +
                                       (string.IsNullOrEmpty(module.Functions[i].Description)
                                            ? string.Empty
                                            : string.Format("({0})", module.Functions[i].Description)),
                                   Value = module.Functions[i].FunctionID,
                                   IsCheckbox = true
                               };
                node.Attributes["Type"] = "Function";
                parentNode.ChildNodes.Add(node);
                LoadFunctions(node, module.Functions[i]);
                LoadOperations(node, module.Functions[i]);
            }
        }

        private static void LoadFunctions(TreeNode parentNode, Function function)
        {
            for (int i = 0; i < function.Functions.Count; i++)
            {
                var node = new TreeNode
                {
                    Text =
                        function.Functions[i].Name +
                        (string.IsNullOrEmpty(function.Functions[i].Description)
                             ? string.Empty
                             : string.Format("({0})", function.Functions[i].Description)),
                    Value = function.Functions[i].FunctionID,
                    IsCheckbox = true
                };
                node.Attributes["Type"] = "Function";
                parentNode.ChildNodes.Add(node);
                LoadFunctions(node, function.Functions[i]);
                LoadOperations(node, function.Functions[i]);
            }
        }

        private static void LoadOperations(TreeNode parentNode, Function function)
        {
            for (int i = 0; i < function.Operations.Count; i++)
            {
                var node = new TreeNode
                               {
                                   Text = function.Operations[i].Name,
                                   Value = function.Operations[i].OperationID,
                                   IsCheckbox = true
                               };
                node.Attributes["Type"] = "Operation";
                parentNode.ChildNodes.Add(node);
            }
        }

        private static void ClearChecked(IEnumerable<TreeNode> nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.IsCheckbox == true)
                {
                    node.Checked = false;
                }
                ClearChecked(node.ChildNodes);
            }
        }

        private void LoadPermission()
        {
            var service = ServiceContainer.GetService<ISecurityManageService>();

            if (treeRoles != null)
            {
                if (treeRoles.SelectedNode != null)
                {
                    Guid roleId = treeRoles.SelectedNode.Value.ToGuid();

                    //change module function permission
                    ClearChecked(tvFunctions.Nodes);
                    var privilleges = (Dictionary<Guid, string[]>)ViewState["Privilege"];
                    string[] functions = privilleges == null || !privilleges.ContainsKey(roleId)
                                             ? service.GetRolePermission(roleId)
                                             : privilleges[roleId];
                    foreach (string s in functions)
                    {
                        TreeNode node = tvFunctions.FindByValue(s);
                        if (node != null)
                        {
                            node.Checked = true;
                        }
                    }
                }
            }


            //var dataFilterService = ServiceContainer.GetService<IDataFilterService>();
            //foreach (var dataFilter in dataFilterService.GetDataFilterNames())
            //{
            //    foreach (TabPanel tab in tabContainer.Tabs)
            //    {
            //        if (tab.HeaderText == dataFilter)
            //        {
            //            var editor = (DataFilterEditor)tab.FindControl("DataFilterEditor");
            //            if (editor != null)
            //            {
            //                editor.PopulatePermission(roleId);
            //            }
            //            break;
            //        }
            //    }
            //}
        }

        protected void btnRefreshRoles_Click(object sender, EventArgs e)
        {
            LoadRoles();
        }

        protected void btnRefreshPermission_Click(object sender, EventArgs e)
        {
            LoadPermission();
        }

        private static void GetCheckedFunctions(IEnumerable<TreeNode> nodes, ICollection<string> functions)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Checked)
                {
                    functions.Add(node.Value);
                }
                GetCheckedFunctions(node.ChildNodes, functions);
            }
        }

        protected void btnDeleteRole_Click(object sender, EventArgs e)
        {
            var service = ServiceContainer.GetService<ISecurityManageService>();
            if (service.RemoveRole(fieldValue.Value.ToGuid()))
            {
                LoadRoles();
            }
        }

        protected void SavePrivilegeSetting()
        {
            var roleId = treeRoles.SelectedNode.Value.ToGuid();
            var transaction = new Transaction(IsolationLevel.ReadCommitted, "Save Permission");
            try
            {
                var functions = new List<string>();
                GetCheckedFunctions(tvFunctions.Nodes, functions);
                var service = ServiceContainer.GetService<ISecurityManageService>();
                if (service.SavePermission(roleId, functions.ToArray(), transaction))
                {
                    transaction.Commit();
                    base.Success("保存成功 !");
                    //base.Success(GetResourceString("SaveRoleOK"));
                }

            }
            catch (Exception)
            {
                transaction.Rollback();
                throw;
            }
        }

        [WebMethod, ScriptMethod]
        public static Boolean AddRole(string roleName)
        {
            var roleCollection = new RoleCollection();
            var intCount = roleCollection.GetDbCount(RoleFields.RoleName == roleName.Trim());
            if (intCount > 0)
            {
                return false;
            }
            var service = ServiceContainer.GetService<ISecurityManageService>();
            foreach (var role in service.GetRoles())
            {
                if (string.Compare(role.RoleName, roleName, true) == 0)
                {
                    return false;
                }
            }
            service.AddRole(roleName);
            return true;
        }
        [WebMethod, ScriptMethod]
        public static Boolean ModifyRole(Guid roleId, string roleName)
        {
            var service = ServiceContainer.GetService<ISecurityManageService>();
            foreach (var role in service.GetRoles())
            {
                if (role.RoleID != roleId && string.Compare(role.RoleName, roleName, true) == 0)
                {
                    return false;
                }
            }
            service.ChangeRoleName(roleId, roleName);
            return true;
        }
    }
}